<template>
  <view class="fu-pull-refresh">
    <!-- 下拉刷新区域 -->
    <view 
      class="fu-pull-refresh__header"
      :style="{ transform: `translateY(${translateY}px)` }"
    >
      <view class="fu-pull-refresh__content">
        <!-- 下拉提示 -->
        <view v-if="status === 'pulling'" class="fu-pull-refresh__text">
          {{ pullingText }}
        </view>
        
        <!-- 释放提示 -->
        <view v-else-if="status === 'loosing'" class="fu-pull-refresh__text">
          {{ loosingText }}
        </view>
        
        <!-- 加载中 -->
        <view v-else-if="status === 'loading'" class="fu-pull-refresh__loading">
          <view class="fu-pull-refresh__spinner"></view>
          <text>{{ loadingText }}</text>
        </view>
      </view>
    </view>
    
    <!-- 内容区域 -->
    <scroll-view
      class="fu-pull-refresh__track"
      scroll-y
      :scroll-top="scrollTop"
      @scroll="onScroll"
      @touchstart="onTouchStart"
      @touchmove.prevent="onTouchMove"
      @touchend="onTouchEnd"
      @scrolltolower="$emit('load-more')"
    >
      <view class="fu-pull-refresh__placeholder" :style="{ height: `${translateY}px` }"></view>
      <slot></slot>
      
      <!-- 加载更多 -->
      <fu-load-more
        :loading="loading"
        :finished="finished"
        :error="error"
        @retry="$emit('load-more')"
      />
    </scroll-view>
  </view>
</template>

<script>
/**
 * @description 下拉刷新组件
 * @property {Boolean} loading 是否处于加载状态
 * @property {Boolean} finished 是否已加载完所有数据
 * @property {Boolean} error 是否加载失败
 * @property {String} pulling-text 下拉过程提示文案
 * @property {String} loosing-text 释放过程提示文案
 * @property {String} loading-text 加载过程提示文案
 * @event {Function} refresh 下拉刷新时触发
 * @event {Function} load-more 上拉加载更多时触发
 */
export default {
  name: 'FuPullRefresh',
  
  props: {
    // 是否处于加载状态
    loading: {
      type: Boolean,
      default: false
    },
    // 是否已加载完所有数据
    finished: {
      type: Boolean,
      default: false
    },
    // 是否加载失败
    error: {
      type: Boolean,
      default: false
    },
    // 下拉过程提示文案
    pullingText: {
      type: String,
      default: '下拉即可刷新...'
    },
    // 释放过程提示文案
    loosingText: {
      type: String,
      default: '释放即可刷新...'
    },
    // 加载过程提示文案
    loadingText: {
      type: String,
      default: '加载中...'
    }
  },
  
  data() {
    return {
      status: 'normal', // normal、pulling、loosing、loading
      startY: 0,
      translateY: 0,
      scrollTop: 0,
      canPull: true
    }
  },
  
  watch: {
    loading(val) {
      if (!val) {
        this.status = 'normal'
        this.translateY = 0
      }
    }
  },
  
  methods: {
    onScroll(e) {
      this.scrollTop = e.detail.scrollTop
      this.canPull = this.scrollTop <= 0
    },
    
    onTouchStart(e) {
      if (this.status === 'loading' || !this.canPull) return
      this.startY = e.touches[0].clientY
      this.status = 'pulling'
    },
    
    onTouchMove(e) {
      if (this.status === 'loading' || !this.canPull) return
      
      const touchY = e.touches[0].clientY
      const distance = touchY - this.startY
      
      if (distance <= 0) {
        this.status = 'normal'
        this.translateY = 0
        return
      }
      
      // 阻尼效果
      this.translateY = Math.min(distance * 0.4, 100)
      
      // 判断是否达到触发距离
      this.status = this.translateY >= 50 ? 'loosing' : 'pulling'
    },
    
    onTouchEnd() {
      if (this.status === 'loading' || !this.canPull) return
      
      if (this.status === 'loosing') {
        this.status = 'loading'
        this.translateY = 50
        this.$emit('refresh')
      } else {
        this.status = 'normal'
        this.translateY = 0
      }
    }
  }
}
</script>

<style lang="scss">
.fu-pull-refresh {
  position: relative;
  height: 100%;
  overflow: hidden;
  
  &__header {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 100rpx;
    background: #f7f8fa;
    transform: translateY(-100%);
    transition: transform 0.3s;
    z-index: 1;
  }
  
  &__content {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
  }
  
  &__text {
    color: #969799;
    font-size: 28rpx;
  }
  
  &__loading {
    display: flex;
    align-items: center;
    
    .fu-pull-refresh__spinner {
      width: 36rpx;
      height: 36rpx;
      margin-right: 12rpx;
      border: 2rpx solid #c8c9cc;
      border-color: #c8c9cc #c8c9cc #c8c9cc transparent;
      border-radius: 50%;
      animation: fu-rotate 0.8s linear infinite;
    }
    
    text {
      color: #969799;
      font-size: 28rpx;
    }
  }
  
  &__track {
    height: 100%;
  }
  
  &__placeholder {
    transition: height 0.3s;
  }
}

@keyframes fu-rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style> 